<?php
/*
Plugin Name: Serasera Login Plugin
Plugin URI: 
Description: 
Version: 0.9.0
Author: Heriniaina Eugene
Author URI: http://hery.serasera.org
*/

ini_set('memory_limit', "32M");

load_plugin_textdomain('auth_serasera','wp-content/mu-plugins/auth_serasera/');

add_action('signup_header', 'serasera_signup_header');

function serasera_signup_header()
{
		if($redirect = get_site_option("seraseraSignupURL")) {
			echo "
				<script language=\"javascript\"
				type=\"text/javascript\">
				<!--
				window.location.replace(
				\"$redirect\");
				-->
				<noscript>
				<a href=\"$redirect\">$redirect</a>
				</noscript>
				</script>
			";
			exit;
		}
}

//login header

//add_action('login_head', 'serasera_login_head');

function serasera_login_head()
{
	global $errors;
	$wp_error = $errors;

	// If cookies are disabled we can't log in even with a valid user+pass
	if ( isset($_POST['testcookie']) && empty($_COOKIE[TEST_COOKIE]) )
		$wp_error->add('test_cookie', __("<strong>ERROR</strong>: Cookies are blocked or not supported by your browser. You must <a href='http://www.google.com/cookies.html'>enable cookies</a> to use WordPress.", 'auth_serasera'));

	// Some parts of this script use the main login form to display a message
	//the first message is removed bcs already sent by wp
	//if		( isset($_GET['loggedout']) && TRUE == $_GET['loggedout'] )			$wp_error->add('loggedout', __('You are now logged out.', 'auth_serasera'), 'message');
	elseif	( isset($_GET['registration']) && 'disabled' == $_GET['registration'] )	$wp_error->add('registerdiabled', __('User registration is currently not allowed.', 'auth_serasera'));
	elseif	( isset($_GET['checkemail']) && 'confirm' == $_GET['checkemail'] )	$wp_error->add('confirm', __('Check your e-mail for the confirmation link.', 'auth_serasera'), 'message');
	elseif	( isset($_GET['checkemail']) && 'newpass' == $_GET['checkemail'] )	$wp_error->add('newpass', __('Check your e-mail for your new password.', 'auth_serasera'), 'message');
	elseif	( isset($_GET['checkemail']) && 'registered' == $_GET['checkemail'] )	$wp_error->add('registered', __('Registration complete. Please check your e-mail.', 'auth_serasera'), 'message');
	


	if ( $wp_error->get_error_code() ) {
		$errors = array();
		
		foreach ( $wp_error->get_error_codes() as $code ) {
			$severity = $wp_error->get_error_data($code);
			foreach ( $wp_error->get_error_messages($code) as $error ) {
				$errors[] = $error;
			}
		}
		if ( !empty($errors) )
		{
			$login_error = base64_encode(serialize($errors));
		}
	}

	echo "
		<script language=\"javascript\"
		type=\"text/javascript\">
		<!--
		window.location.replace(
		\"http://blaogy.org/?login_error=". $login_error."\");
		-->
		</script>
	";
	
}


// Includes
require_once("auth_serasera/nusoap.php");

//require_once();

// *** Begin Admin Config Functions *** //
add_action('admin_menu', 'serasera_addmenu');
function serasera_addmenu() {
	$objCurrUser = wp_get_current_user();
	$objUser = wp_cache_get($objCurrUser->id, 'users');
	if (function_exists('add_options_page') && is_site_admin($objUser->user_login)) {
		add_options_page('Serasera Authentication Options', 'Serasera Options', 9, basename(__FILE__), 'seraseraOptionsPanel');
	}
}

add_action('admin_head', 'serasera_addcss');
function serasera_addcss() {
	echo "<link rel='stylesheet' href='" . get_settings('siteurl') . "/wp-content/plugins/auth_serasera/auth_serasera.css' media='screen' type='text/css' />";
}

function seraseraOptionsPanel() {
	if($_POST['seraseraOptionsSave']) {
		update_site_option('seraseraSignupURL', $_POST['seraseraOptionsSignupURL']);
		update_site_option('seraseraApiKey', $_POST['seraseraOptionsApiKey']);
		update_site_option('seraseraEndPoint', $_POST['seraseraOptionsEndPoint']);
		update_site_option('seraseraAuth', $_POST['seraseraOptionsAuth']);
		
		echo "<div class='updated'><p>Saved Options!</p></div>";
	}
	
	$seraseraSignupURL 			= get_site_option("seraseraSignupURL");
	$seraseraApiKey 			= get_site_option("seraseraApiKey");
	$seraseraEndPoint		= get_site_option("seraseraEndPoint");
	$seraseraAuth			= get_site_option("seraseraAuth");
	$seraseraCookieMarker	= get_site_option("seraseraCookieMarker");

	if($seraseraAuth) {
		$tChecked = "checked";
	}
	else {
		$fChecked = "checked";
	}
	
	echo <<<seraseraForm
	<div class="wrap">
	<h2>serasera Authentication Options</h2>
	<form method="post" id="serasera_auth_options">
		<fieldset class="options">
		<legend>General Server Settings</legend>
		
		<div class="row">
			<span class="description">Serasera Webservice</span>
			<span class="element">
				<input type='text' name='seraseraOptionsEndPoint' value='$seraseraEndPoint' style='width: 300px;' /><br />
				<em>The URI of the webservice.</em>
			</span>
		</div>
		
		<div class="row">
			<span class="description">Api Key</span>
			<span class="element">
				<input type='text' name='seraseraOptionsApiKey' value='$seraseraApiKey' style='width: 300px;' /><br />
				<em>You should have a key to use serasera webservice</em>
			</span>
		</div>
		
		<div class="row">
			<span class="description">Serasera Signup Page</span>
			<span class="element">
				<input type='text' name='seraseraOptionsSignupURL' value='$seraseraSignupURL' style='width: 300px;' /><br />
				<em>When people click on Signup Page</em>
			</span>
		</div>

		<div class="row">
			<span class="description">Enable serasera plugin?</span><br />
			<span class="element">
				<input type='radio' name='seraseraOptionsAuth' value='1' $tChecked/> Yes
				<input type='radio' name='seraseraOptionsAuth' value='0' $fChecked/> No
			</span>
		</div>
		
		<p class="submit"><input type="submit" name="seraseraOptionsSave" value="Save" /></p>
		</fieldset>
	</form>
	</div>
seraseraForm;
}
// *** End Admin Config Functions *** //


// *** Begin User Auth Functions *** //

// This will disabled the chage password dialogs.
// There is no docs so this is the only way i can think of to disable this 'feature'
if (get_site_option("seraseraAuth")) : 
add_filter('show_password_fields', 'getFalse');
function getFalse() {
	return false;
}
endif;

if (get_site_option("seraseraAuth")) {
function wp_authenticate($username, $password) {
	global $wpdb, $error, $current_site, $current_user, $base;
	
	//Make sure we always use lowercase usernames.
	$username = strtolower($username);
	
	$seraseraAuth 			= get_site_option("seraseraAuth");
	$seraseraApiKey 			= get_site_option("seraseraApiKey");
	$seraseraEndPoint		= get_site_option("seraseraEndPoint");
	
	if(!$username) {
		$error = __('<strong>Error</strong>: The username field is empty.', 'auth_serasera');
		return  new WP_Error('wrong_password', $error);
	}
	
	if(!$password) {
		$error = __('<strong>Error</strong>: The password field is empty.', 'auth_serasera');
		return new WP_Error('wrong_password', $error);
	}
	$login = get_userdatabylogin($username);	
	//Bassically if we are already logged in and we try to relogin.
	
	if ($current_user->data->user_login == $username) {
		return new WP_User($login->ID);
	}
	



	//everything is ok

	if ( $login->user_login == $username && $login->user_pass == md5($password)) {
		return new WP_User($login->ID);
	}


	
	//only username is ok => check from webservice and update the password
	if($login->user_login == $username) {
	
		
		$client = new soapclient($seraseraEndPoint, true);
		$err = $client->getError();

		if($err) {
			$error = __('<strong>Error</strong>: Wrong password.', 'auth_serasera');
			Return new WP_Error('wrong_password', $error);
		}

		$param = array('wsid' => $seraseraApiKey, 'username' => $username, 'password' => $password, 'site' => 'blaogy.org');
		$result = $client->call('getUser', $param);

		if ($client->fault) {
			$error = __('<strong>Error</strong>: Wrong password.', 'auth_serasera');
			return new WP_Error('wrong_password', $error);
		} else {
		

			if($result[loggedin] == true) {
				$query = "UPDATE $wpdb->users SET user_pass='" . md5($password) . "' WHERE ID = '$login->ID'";
				$query = apply_filters('update_user_query', $query);
				$wpdb->query( $query );
				Return new WP_User($login->ID);
			} else {
				$error = __('<strong>Error</strong>: Wrong password.', 'auth_serasera');
				return new WP_Error('wrong_password', $error);
			}
		}
	} else {
		// a complete new user from the webservice
	
		$client = new soapclient($seraseraEndPoint, true);
		$err = $client->getError();

		if($err) {
			$error = __('<strong>Error</strong>: Network error.', 'auth_serasera') . var_export($err, true);
			Return new WP_Error('wrong_password', $error);
		}

		$param = array('wsid' => $seraseraApiKey, 'username' => $username, 'password' => $password, 'site' => 'blaogy.org');
		$result = $client->call('getUser', $param);
		
		if ($client->fault) {
			$error = __('<strong>Error</strong>: Wrong password.', 'auth_serasera');
			return new WP_Error('wrong_password', $error);
		} else {
			if($result[loggedin] == true) {

				// call the registration function to create a wordpress user account for this
				// successfully authenticated user
				require_once( ABSPATH . WPINC . '/registration.php');
				
				if ( !username_exists( $username ) ) {
					//Create the user
					//$sPassword = generate_random_password();
					define( "WP_INSTALLING", true );
					$user_id = wpmu_create_user( $username, $password, $result[email] );
					
					if (!$user_id) {
						$error = __('<strong>Error</strong>: Account Creation Failed.', 'auth_serasera');
						return new WP_Error('wrong_password', $error);
					}
					
					//Update their first and last name from ldap
					update_usermeta( $user_id, 'first_name', $result[firstname] );
					update_usermeta( $user_id, 'last_name', $result[lastname] );
					
					//This is for plugin events
					do_action( 'wpmu_new_user', $user_id );
					do_action('wpmu_activate_user', $user_id, $password);
					
					$domain = strtolower( wp_specialchars( $username ) );
					if( constant( "VHOST" ) == 'yes' ) {
						$newdomain = $domain . "." . $current_site->domain;
						$path = $base;
					} else {
						$newdomain = $current_site->domain;
						$path = $base . $domain . '/';
					}
					
					
					//Becuase WPMU has a bug in the create blog function we need this code 
					//To prevent errors with the wpmu_create_blog function.  See Ticket #184
					//$result = $wpdb->query( "CREATE TABLE wp_" . $user_id . "_options (option_id bigint(20) NOT NULL auto_increment, blog_id int(11) NOT NULL default 0, option_name varchar(64) NOT NULL default '', option_can_override enum('Y','N') NOT NULL default 'Y', option_type int(11) NOT NULL default 1, option_value longtext NOT NULL, option_width int(11) NOT NULL default 20, option_height int(11) NOT NULL default 8, option_description tinytext NOT NULL, option_admin_level int(11) NOT NULL default 1, autoload enum('yes','no') NOT NULL default 'yes', PRIMARY KEY  (option_id,blog_id,option_name), KEY option_name (option_name)) ENGINE=MyISAM DEFAULT CHARSET=utf8;" );
					
					//Create and update the users blog.
					$meta = apply_filters('signup_create_blog_meta', array ('lang_id' => 'mg', 'public' => 1));
					$blog_id = wpmu_create_blog($newdomain, $path, "Blaogin'i " . $username , $user_id, $meta);
					do_action('wpmu_activate_blog', $blog_id, $user_id, $password, "Blaogin'i " . $username, $meta);
					
					//Must recreated the login object for our shiny NEW users.
					$login = get_userdatabylogin($username);
					
					//Setup redirection to users home directory.
					if (!strpos($_REQUEST['redirect_to'], $username)) {
						$_REQUEST['redirect_to'] = $username . "/" . $_REQUEST['redirect_to'];
					}
					Return new WP_User($login->ID);
				} elseif ( !username_exists( $username ) && !$seraseraCreateAcct ) {
					$error = __('<strong>Error</strong>: Local account does not exist.', 'auth_serasera');
					return new WP_Error('wrong_password', $error);
				}

			} else {
				$error = __('<strong>Error</strong>: Wrong login and password.', 'auth_serasera');
				return new WP_Error('wrong_password', $error);
			}
		}
				
		//At this point we must have a login object!
		//I dont see how we couldn't but just in case.
		if (!$login) {
			$error = __('<strong>Error</strong>: Unknown Near Line 274 auth_serasera.php.', 'auth_serasera');
			return new WP_Error('wrong_password', $error);
		}
		
		//Added to atempt to recreate login correctly
		//I think this is for account suspentions
		$primary_blog = get_usermeta( $login->ID, "primary_blog" );
		if( $primary_blog ) {
			$details = get_blog_details( $primary_blog );
			if( is_object( $details ) ) {
				if( $details->archived == 1 || $details->spam == 1 || $details->deleted == 1 ) {
					$error = __('<strong>Error</strong>: Blog suspended.', 'auth_serasera');
					return new WP_Error('wrong_password', $error);
				}
			}
		}
				

		// Bad Coding Practiace
		// We can get to this point in code and exit without a status.
		// This is why we dont exit at multipul points boys and girls.
		return new WP_Error();
	} // End if (LDAP_ENABLED)

		//We are Not using LDAP So we need to auth normally 
		//This is all original code pulled from the pluggable.php 
		//file located in the wp-plugins folder.  Comments were 
		//added to help figure out what is going on.
		
		//Now I think this is trying to get the users data. 
		//I think the site admin and domain admins are stored 
		//seperatly from normal users??? Just guessing as there 
		//is NO DOCUMENTATION!!!
		//This entire code block seems a bit useless to me.  Definitly not needed if we use ldap.
		if (!$login) {
			if( is_site_admin( $username ) ) {
				//If Site Admin
				//FYI This does exactly the same thing as $login = get_userdatabylogin( $username );
				//which has already been done above?!?
				unset( $login );
				$userdetails = get_userdatabylogin( $username );
				$login->user_login = $username;
				$login->user_pass = $userdetails->user_pass;
			} else {
				//If Domain Admin
				$admins = get_admin_users_for_domain();
				reset( $admins );
				while( list( $key, $val ) = each( $admins ) ) 
				{ 
					if( $val[ 'user_login' ] == $username ) {
						unset( $login );
						$login->user_login = $username;
						$login->user_pass  = $val[ 'user_pass' ];
					}
				}
			}
		}
		
		if (!$login) {
			//If we didnt find a user originally and we didnt get one from the above code...
			$error = __('<strong>Error</strong>: Wrong username.', 'auth_serasera');
			return new WP_Error('wrong_password', $error);
		} else {
			//Setup some kind of default blog for the user...
			$primary_blog = get_usermeta( $login->ID, "primary_blog" );
			if( $primary_blog ) {
				$details = get_blog_details( $primary_blog );
				if( is_object( $details ) ) {
					if( $details->archived == 1 || $details->spam == 1 || $details->deleted == 1 ) {
						$error = __('<strong>Error</strong>: Blog suspended.', 'auth_serasera');
						return new WP_Error('wrong_password', $error);
					}
				}
			}
			
			//Setup redirection to users home directory.
			if (!strpos($_REQUEST['redirect_to'], $username)) {
				$_REQUEST['redirect_to'] = $username . "/" . $_REQUEST['redirect_to'];
			}
			
			// If the password is already_md5, it has been double hashed.
			// Otherwise, it is plain text.
			if ( $login->user_login == $username && $login->user_pass == md5($password)) {
				return new WP_User($login->ID);
			} else {
				$error = __('<strong>Error</strong>: Incorrect password.', 'auth_serasera');
				$pwd = '';
				return new WP_Error('wrong_password', $error);
			}
		}
	}
}


?>
